#pragma once
#ifndef _LPAGAMEENGINE_CORE_PATTERNS_SINGLETON_H_
#define _LPAGAMEENGINE_CORE_PATTERNS_SINGLETON_H_

#include <cassert>
#include <memory>
#include <iostream>

/**
 * @class	Singleton
 *
 * @brief	Singleton based on auto_ptr. This great singleton template was grabbed from http://www.gamedev.net/topic/301651-singleton-solution-w-auto_ptr/
 *
 * @author	cozman at http://www.gamedev.net/user/20136-cozman/
 * @date	15/09/2011
*******************************************************
* Example of use
* class Something : public Singleton<Something>
* {
*	friend class Singleton<Something>;
*	friend class std::auto_ptr<Something>;
* private:
* 	Something() { std::cout << "created" << std::endl; }
*	~Something() { std::cout << "destroyed" << std::endl; }
*};
*******************************************************/

template<class T>
class Singleton
{
public:   
	static void initSingleton()
	{
		// Puede que este assert sea una sobreingenieria. Esta bien comprobar que se inicializa una vez, pero  en realidad choca con proyectos grandes
		// donde los componentes diversos y no podemos garantizar el orden de inicializacion, provocando problemas con assert en test automaticos y en otras partes
		// por lo que prefiero borrar este assert y comprobarlo en runtime.
		//assert(instance_.get() == 0);

		if(instance_.get() == 0)
			instance_ = std::auto_ptr<T>(new T);
	}

	static T& getSingleton()
	{
		assert(instance_.get() != 0);

		return *instance_;
	}

	static void destroySingleton()
	{
		assert(instance_.get() != 0);

		instance_.reset();
	}

	virtual ~Singleton()=0;

private:

	static std::auto_ptr<T> instance_;
};

template<class T> 
std::auto_ptr<T> Singleton<T>::instance_(0);

template<class T>
Singleton<T>::~Singleton() { }

#endif //_LPAGAMEENGINE_CORE_PATTERNS_SINGLETON_H_
